/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ships.core.models;

import ships.core.AbstractDataBuffer;

/**
 *
 * @author fqhuy
 */
public class ComponentSampleModel extends SampleModel {

    /** Offsets for all bands in data array elements. */
    protected int bandOffsets[];
    /** Index for each bank storing a band of image data. */
    protected int[] bankIndices;
    /**
     * The number of bands in this
     * <code>ComponentSampleModel</code>.
     */
    protected int numBands = 1;
    /**
     * The number of banks in this
     * <code>ComponentSampleModel</code>.
     */
    protected int numBanks = 1;
    /**
     *  Line stride (in data array elements) of the region of image
     *  data described by this ComponentSampleModel.
     */
    protected int scanlineStride;
    /** Pixel stride (in data array elements) of the region of image
     *  data described by this ComponentSampleModel.
     */
    protected int pixelStride;

    public ComponentSampleModel(
            int w, int h,
            int pixelStride,
            int scanlineStride,
            int bandOffsets[]) {
        super(w, h, bandOffsets.length);
        this.pixelStride = pixelStride;
        this.scanlineStride = scanlineStride;
        this.bandOffsets = (int[]) bandOffsets.clone();
        numBands = bandOffsets.length;
        if (pixelStride < 0) {
            throw new IllegalArgumentException("Pixel stride must be >= 0");
        }
        // TODO - bug 4296691 - remove this check
        if (scanlineStride < 0) {
            throw new IllegalArgumentException("Scanline stride must be >= 0");
        }
        if (numBands < 1) {
            throw new IllegalArgumentException("Must have at least one band.");
        }
        //if ((dataType < DataBuffer.TYPE_BYTE) ||
        //    (dataType > DataBuffer.TYPE_DOUBLE)) {
        //    throw new IllegalArgumentException("Unsupported dataType.");
        //}
        bankIndices = new int[numBands];
        for (int i = 0; i < numBands; i++) {
            bankIndices[i] = 0;
        }
    }

    public ComponentSampleModel(
            int w, int h,
            int pixelStride,
            int scanlineStride,
            int bankIndices[],
            int bandOffsets[]) {
        super(w, h, bandOffsets.length);
        this.pixelStride = pixelStride;
        this.scanlineStride = scanlineStride;
        this.bandOffsets = (int[]) bandOffsets.clone();
        this.bankIndices = (int[]) bankIndices.clone();
        if (pixelStride < 0) {
            throw new IllegalArgumentException("Pixel stride must be >= 0");
        }
        // TODO - bug 4296691 - remove this check
        if (scanlineStride < 0) {
            throw new IllegalArgumentException("Scanline stride must be >= 0");
        }
        //if ((dataType < DataBuffer.TYPE_BYTE) ||
        //    (dataType > DataBuffer.TYPE_DOUBLE)) {
        //    throw new IllegalArgumentException("Unsupported dataType.");
        //}
        int maxBank = bankIndices[0];
        if (maxBank < 0) {
            throw new IllegalArgumentException("Index of bank 0 is less than "
                    + "0 (" + maxBank + ")");
        }
        for (int i = 1; i < bankIndices.length; i++) {
            if (bankIndices[i] > maxBank) {
                maxBank = bankIndices[i];
            } else if (bankIndices[i] < 0) {
                throw new IllegalArgumentException("Index of bank " + i
                        + " is less than 0 ("
                        + maxBank + ")");
            }
        }
        numBanks = maxBank + 1;
        numBands = bandOffsets.length;
        if (bandOffsets.length != bankIndices.length) {
            throw new IllegalArgumentException("Length of bandOffsets must "
                    + "equal length of bankIndices.");
        }
    }

    @Override
    public <T extends Number> T getSample(int x, int y, int b, AbstractDataBuffer data) {
        if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
            throw new ArrayIndexOutOfBoundsException("Coordinate out of bounds!");
        }
        T sample = (T)data.getElem(bankIndices[b], y * scanlineStride + x * pixelStride + bandOffsets[b]);
        return sample;
    }

    @Override
    public SampleModel createCompatibleSampleModel(int w, int h) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public SampleModel createSubsetSampleModel(int[] bands) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public  <T extends Number> AbstractDataBuffer createDataBuffer(MemoryModel memoryModel, T initVal) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int[] getSampleSize() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getSampleSize(int band) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
